#include "../ocl/code.h"

void ocl_code_init( ocl_code *code )
{
	assert( code );
	memset( code, 0, sizeof(ocl_code) );
	if( ocl_logfile ) fprintf( ocl_logfile, "[ocl_code_init]\n");
}




void ocl_code_quit( ocl_code *code )
{
	
	if( code )
	{
		if( ocl_logfile ) fprintf( ocl_logfile, "[ocl_code_quit]counts=%u\n", (unsigned)(code->count));
		while( code->count > 0 )
		{
			ocl_chunk *chunk = mds_list_pop_back(ocl_chunk, code );
			ocl_chunk_delete( chunk );
		}
		memset( code, 0, sizeof(ocl_code) );
	}
}


int ocl_code_read( ocl_code *code, const char *filename )
{
	static const char fn[] = "[ocl_code_read]";
	
	FILE      *fp    = NULL;
	long       nb    = 0;
	ocl_chunk *chunk = NULL;
	assert( code );
	ocl_errno = CL_SUCCESS;
	
	/* open the file */
	if( ocl_logfile ) fprintf( ocl_logfile, "%s Open '%s'\n", fn, filename );
	fp = fopen( filename, "rb" );
	if( ! fp )
		return -1;
	
	if( (nb = mds_file_length(fp) ) < 0 )
		goto ERROR;
	
	if( ocl_logfile ) fprintf( ocl_logfile, "%s Found %ld bytes\n", fn, nb );
	
	/* rewind */
	if( fseek(fp,0,SEEK_SET) < 0 ) goto ERROR;
	
	/* create chunk */
	if( NULL == ( chunk = ocl_chunk_create( nb ) ) )
	{
		goto ERROR;
	}
	
	/* read chunk */
	if( ocl_logfile ) fprintf( ocl_logfile, "%s Reading\n", fn);
	if( chunk->size != fread( chunk->data, 1, chunk->size, fp ) )
	{
		ocl_chunk_delete(chunk);
		goto ERROR;
	}
	fclose(fp);
	
	
	ocl_code_add( code, chunk );
	assert( code->count > 0 );
	
	if( ocl_logfile ) fprintf( ocl_logfile, "%s Loaded\n", fn );
	return 0;
	
ERROR:
	fclose(fp);
	return -1;
}

int ocl_code_copy( ocl_code *code, const void *data, size_t size )
{
	assert( code );
	ocl_errno = CL_SUCCESS;
	if( size )
	{
		assert(data!=NULL);
		ocl_chunk *chunk = ocl_chunk_create( size );
		if( !chunk )
			return -1;
		memcpy( chunk->data, data, size );
		ocl_code_add( code, chunk );
	}
	return 0;
	
}

void ocl_code_add( ocl_code *code, ocl_chunk *chunk )
{
	assert( code );
	assert( chunk );
	assert( NULL == chunk->next );
	assert( NULL == chunk->prev );
	mds_list_push_back( code, chunk );
}


